package com.zhentao.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhentao.dto.QueryConditionDto;
import com.zhentao.dto.SummaryQueryResultDto;
import com.zhentao.pojo.DataCollection;
import com.zhentao.service.DataCollectionService;
import com.zhentao.service.DataQueryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 数据查询服务实现类
 * 根据业务流程需求实现三种查询类型
 */
@Service
public class DataQueryServiceImpl implements DataQueryService {
    
    @Autowired
    private DataCollectionService dataCollectionService;
    
    // 最小列集合（包含进出口类型）
    private static final String[] MIN_COLUMNS = new String[]{
            "customs_area", "declare_no", "item_no",
            "amount_cny", "amount_usd", "goods_quantity",
            "import_export_type"
    };

    @Override
    public List<SummaryQueryResultDto> summaryQuery(QueryConditionDto queryCondition) {
        if (!validateQueryCondition(queryCondition)) {
            throw new IllegalArgumentException("查询条件验证失败");
        }
        if (queryCondition.getGroupDimensions() != null && queryCondition.getGroupDimensions().size() > 3) {
            throw new IllegalArgumentException("分组维度最多只能选择3个");
        }
        QueryWrapper<DataCollection> queryWrapper = buildQueryWrapper(queryCondition);
        queryWrapper.select(MIN_COLUMNS);
        List<DataCollection> dataList = dataCollectionService.list(queryWrapper);
        return aggregateData(dataList, queryCondition.getGroupDimensions());
    }
    
    @Override
    public List<SummaryQueryResultDto> summaryQueryDrillDown(QueryConditionDto queryCondition, List<String> drillDownPath) {
        QueryWrapper<DataCollection> queryWrapper = buildQueryWrapper(queryCondition);
        queryWrapper.select(MIN_COLUMNS);
        List<DataCollection> dataList = dataCollectionService.list(queryWrapper);
        return aggregateData(dataList, drillDownPath);
    }
    
    @Override
    public IPage<DataCollection> dataQuery(QueryConditionDto queryCondition) {
        QueryWrapper<DataCollection> queryWrapper = buildQueryWrapper(queryCondition);
        if (queryCondition.getOutputFields() != null && !queryCondition.getOutputFields().isEmpty()) {
            queryWrapper.select(queryCondition.getOutputFields().toArray(new String[0]));
        } else {
            // 查询所有字段，不限制为MIN_COLUMNS
            queryWrapper.select("*");
        }
        Page<DataCollection> page = new Page<>(queryCondition.getPageNum(), queryCondition.getPageSize());
        return dataCollectionService.page(page, queryWrapper);
    }
    
    @Override
    public IPage<DataCollection> rawDataQuery(QueryConditionDto queryCondition) {
        QueryWrapper<DataCollection> queryWrapper = buildQueryWrapper(queryCondition);
        if (queryCondition.getOutputFields() != null && !queryCondition.getOutputFields().isEmpty()) {
            queryWrapper.select(queryCondition.getOutputFields().toArray(new String[0]));
        } else {
            // 查询所有字段，不限制为MIN_COLUMNS
            queryWrapper.select("*");
        }
        Page<DataCollection> page = new Page<>(queryCondition.getPageNum(), queryCondition.getPageSize());
        return dataCollectionService.page(page, queryWrapper);
    }
    
    @Override
    public Object exportQueryResult(QueryConditionDto queryCondition, String exportType) {
        switch (exportType) {
            case "SUMMARY":
                return summaryQuery(queryCondition);
            case "DATA":
                return dataQuery(queryCondition);
            case "RAW_DATA":
                return rawDataQuery(queryCondition);
            default:
                throw new IllegalArgumentException("不支持的导出类型: " + exportType);
        }
    }
    
    @Override
    public List<String> getAvailableGroupDimensions(String queryType) {
        List<String> dimensions = new ArrayList<>();
        if ("SUMMARY_QUERY".equals(queryType)) {
            dimensions.add("customs_area");
            dimensions.add("declare_no");
            dimensions.add("item_no");
            dimensions.add("import_export_type");
        }
        return dimensions;
    }
    
    @Override
    public List<String> getAvailableOutputFields(String queryType) {
        List<String> fields = new ArrayList<>();
        fields.add("amount_cny");
        fields.add("amount_usd");
        fields.add("goods_quantity");
        fields.add("declare_count");
        fields.add("record_count");
        fields.add("import_export_type");
        return fields;
    }
    
    @Override
    public boolean validateQueryCondition(QueryConditionDto queryCondition) {
        if (queryCondition.getGroupDimensions() != null && queryCondition.getGroupDimensions().size() > 3) {
            return false;
        }
        if (!StringUtils.hasText(queryCondition.getQueryType())) {
            return false;
        }
        return true;
    }
    
    /**
     * 构建查询条件（仅使用旧表存在的列；其余条件忽略）
     */
    private QueryWrapper<DataCollection> buildQueryWrapper(QueryConditionDto queryCondition) {
        QueryWrapper<DataCollection> queryWrapper = new QueryWrapper<>();
        // 新增：按进出口类型过滤
        if (StringUtils.hasText(queryCondition.getImportExportType())) {
            queryWrapper.eq("import_export_type", queryCondition.getImportExportType());
        }
        if (queryCondition.getFilterConditions() != null) {
            for (Map.Entry<String, Object> entry : queryCondition.getFilterConditions().entrySet()) {
                String field = entry.getKey();
                Object value = entry.getValue();
                if (value instanceof String && ((String) value).contains("%")) {
                    queryWrapper.like(field, (String) value);
                } else {
                    queryWrapper.eq(field, value);
                }
            }
        }
        return queryWrapper;
    }
    
    private List<SummaryQueryResultDto> aggregateData(List<DataCollection> dataList, List<String> groupDimensions) {
        if (groupDimensions == null || groupDimensions.isEmpty()) {
            return Collections.singletonList(aggregateSingleGroup(dataList));
        }
        Map<String, List<DataCollection>> groupedData = groupDataByDimensions(dataList, groupDimensions);
        return groupedData.entrySet().stream()
                .map(entry -> {
                    SummaryQueryResultDto result = aggregateSingleGroup(entry.getValue());
                    result.setDimensionValues(parseGroupKey(entry.getKey(), groupDimensions));
                    result.setLevel(groupDimensions.size());
                    result.setDrillable(groupDimensions.size() < 3);
                    result.setDrillPath(groupDimensions);
                    return result;
                })
                .collect(Collectors.toList());
    }
    
    private Map<String, List<DataCollection>> groupDataByDimensions(List<DataCollection> dataList, List<String> groupDimensions) {
        return dataList.stream().collect(Collectors.groupingBy(data -> {
            StringBuilder key = new StringBuilder();
            for (String dimension : groupDimensions) {
                String value = getDimensionValue(data, dimension);
                key.append(value).append("|");
            }
            return key.toString();
        }));
    }
    
    private String getDimensionValue(DataCollection data, String dimension) {
        switch (dimension) {
            case "customs_area":
                return data.getCustomsArea();
            case "declare_no":
                return data.getDeclareNo();
            case "item_no":
                return data.getItemNo();
            case "import_export_type":
                return data.getImportExportType();
            default:
                return "未知";
        }
    }
    
    private Map<String, String> parseGroupKey(String groupKey, List<String> groupDimensions) {
        Map<String, String> dimensionValues = new HashMap<>();
        String[] values = groupKey.split("\\|");
        for (int i = 0; i < groupDimensions.size() && i < values.length; i++) {
            dimensionValues.put(groupDimensions.get(i), values[i]);
        }
        return dimensionValues;
    }
    
    private SummaryQueryResultDto aggregateSingleGroup(List<DataCollection> dataList) {
        SummaryQueryResultDto result = new SummaryQueryResultDto();
        long declareCount = dataList.stream()
                .map(DataCollection::getDeclareNo)
                .filter(Objects::nonNull)
                .distinct()
                .count();
        result.setDeclareCount(declareCount);
        result.setRecordCount((long) dataList.size());
        BigDecimal totalAmountCny = dataList.stream()
                .map(data -> data.getAmountCny() != null ? BigDecimal.valueOf(data.getAmountCny()) : BigDecimal.ZERO)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        result.setAmountCny(totalAmountCny);
        BigDecimal totalAmountUsd = dataList.stream()
                .map(data -> data.getAmountUsd() != null ? BigDecimal.valueOf(data.getAmountUsd()) : BigDecimal.ZERO)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        result.setAmountUsd(totalAmountUsd);
        long totalGoodsQuantity = dataList.stream()
                .mapToLong(data -> data.getGoodsQuantity() != null ? data.getGoodsQuantity() : 0L)
                .sum();
        result.setGoodsQuantity(totalGoodsQuantity);
        return result;
    }
} 